﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using Confucius.entity;
using System.Windows.Resources;
using System.Linq;
using System.Xml.Linq;
using DBContent.Model;
using Confucius.utils;
using Confucius.dao;

namespace Confucius.daoImpl
{
    /// <summary>
    /// Author:Liangchuan Gu
    /// date:2012-04-08
    /// </summary>
    public class NPCDAOImpl : NPCDAO
    {
        public const int MAX_DIALOG_BRANCH  = 4;

	    public NPCDAOImpl() {}

        public List<NPC> retrieveNPCs(String gameID) 
        {
            List<NPC> npcs = new List<NPC>();
            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/npc.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var npcRecords = from record in loadedData.Descendants("npc")
                                  select record;

                foreach (XElement record in npcRecords)
                {
                    NPC newNPC = new NPC();

                    newNPC.NpcID = (string)record.Element("npcID").Value;
                    newNPC.Greeting = (string)record.Element("greeting").Value;
                    newNPC.Name = (string)record.Element("name").Value;
                    newNPC.IconID = (string)record.Element("iconID").Value;
                    newNPC.Chattable = (string)record.Element("chattable").Value;
                    newNPC.FigureID = (string)record.Element("figureID").Value;
                    newNPC.DialogID = (string)record.Element("dialogID").Value;
                    newNPC.Lng = (float)Convert.ToDouble((string)record.Element("lng").Value);
                    newNPC.Lat = (float)Convert.ToDouble((string)record.Element("lat").Value);

                    npcs.Add(newNPC);
                }
            }
            catch (Exception e)
            {
                throw new Exception("Could not load triggerIDs from DB. Info is: " + e.Message);
            }

            return npcs;
        }

        public NPC readNPC(String npcID, String gameID) 
        {
            NPC npc = new NPC();

            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/npc.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var npcs = from record in loadedData.Descendants("npc")
                            select record;

                foreach (XElement npcRecord in npcs)
                {
                    string id = (string)npcRecord.Element("npcID").Value;
                    if (id.Equals(npcID))
                    {
                        npc.NpcID = id;
                        npc.Greeting = (string)npcRecord.Element("greeting").Value;
                        npc.Name = (string)npcRecord.Element("name").Value;
                        npc.IconID = (string)npcRecord.Element("iconID").Value;
                        npc.Chattable = (string)npcRecord.Element("chattable").Value;
                        npc.FigureID = (string)npcRecord.Element("figureID").Value;
                        npc.DialogID = (string)npcRecord.Element("dialogID").Value;
                        npc.Lng = (float)Convert.ToDouble((string)npcRecord.Element("lng").Value);
                        npc.Lat = (float)Convert.ToDouble((string)npcRecord.Element("lat").Value);

                        break;
                    }
                }

            }
            catch (Exception e)
            {
                throw new Exception("Could not load NPC from DB. Info is: " + e.Message);
            }

            return npc;
        }

        public DialogNode readDialogNode(String dialogNodeID, String gameID) 
        {
            DialogNode dialogNode = new DialogNode();

            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/dialognode.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var dialogs = from record in loadedData.Descendants("dialognode")
                           select record;

                foreach (XElement dialogRecord in dialogs)
                {
                    string id = (string)dialogRecord.Element("dialogNodeID").Value;
                    if (id.Equals(dialogNodeID))
                    {
                        dialogNode.DialogNodeID = id;
                        dialogNode.Name = (string)dialogRecord.Element("name").Value;
                        dialogNode.ContainedMediaID = (string)dialogRecord.Element("containedMediaID").Value;
                        dialogNode.InteractionType = (string)dialogRecord.Element("interactionType").Value;
                        dialogNode.NodeType = (string)dialogRecord.Element("nodeType").Value;
                        dialogNode.DisplayText = (string)dialogRecord.Element("displayText").Value;

                        break;
                    }
                }

            }
            catch (Exception e)
            {
                throw new Exception("Could not load trigger from DB. Info is: " + e.Message);
            }

            return dialogNode;
        }

        public List<DialogNodeOrder> retrieveAdjacentDialogNodeOrder(
            String fromDialogNodeID, String gameID) 
        {
            List<DialogNodeOrder> dialogNodeOrders = new List<DialogNodeOrder>();
            int collectDialogNodeNum = 0;
            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/dialognodeorder.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);

                var dnOderRecords = from record in loadedData.Descendants("dialogNodeOrder")
                                 select record;

                foreach (XElement record in dnOderRecords)
                {
                    DialogNodeOrder newDNOrder = new DialogNodeOrder();

                    newDNOrder.FromNodeID = (string)record.Element("fromNodeID").Value;
                    newDNOrder.ToNodeID = (string)record.Element("toNodeID").Value;
                    newDNOrder.Answer = (string)record.Element("answer").Value;
                    newDNOrder.AnswerOrder = Convert.ToInt32((string)record.Element("answerOrder").Value);

                    if (newDNOrder.FromNodeID.Equals(fromDialogNodeID))
                    {
                        dialogNodeOrders.Add(newDNOrder);
                        collectDialogNodeNum++;
                    }
                    if (collectDialogNodeNum == MAX_DIALOG_BRANCH)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Could not load triggerIDs from DB. Info is: " + e.Message);
            }

            return dialogNodeOrders;
        }

        public String readNPCStatus(String npcID)
        {
            DBNpc dbNpc = new DBNpc();
            dbNpc.NpcID = npcID;
            String itemStatus = ConfuciusDBHelper.getNpcStatus(dbNpc);

            return itemStatus;
        }

        public void updateNPCStatus(String npcID, String status) 
        {
            DBNpc dbNpc = new DBNpc();
            dbNpc.NpcID = npcID;
            dbNpc.Status = status;
            ConfuciusDBHelper.updateNpcStatus(dbNpc);
        }
    }
}
